package compiler.ast;

import java.io.PrintStream;
import java.util.ArrayList;

import compiler.tac.BasicBlock;
import compiler.tac.ThreeAddressCode;

public class Term {
	ArrayList<SignedFactor> children;
	char sign; // '+' or '-'
	
	public Term(SignedFactor firstChdr) {
		this.children = new ArrayList<SignedFactor>();
		children.add(firstChdr);
	}
	
	public void addFactor(SignedFactor child) {
		children.add(child);
	}
	
	public void setSign(char sign) {
		this.sign = sign;
	}
	
	public char getSign() {
		return sign;
	}

	public void printDotFormat(PrintStream out, String node) {
		String firstNode;
		if (children.size() == 1) {
			firstNode = node;
		} else {
			firstNode = node+0;
			String leftChild = firstNode;
			for (int i = 1; i < children.size(); i++) {
				String rightChild = node+i;
				String oprtNode = (i == children.size()-1) ? node : node+"md"+i;
				out.println(oprtNode+" [label=\""+children.get(i).getSign()+"\"];");
				out.println(oprtNode+"->"+leftChild+";");
				out.println(oprtNode+"->"+rightChild+";");
				children.get(i).printDotFormat(out, rightChild);
				leftChild = oprtNode;
			}
		}
		children.get(0).printDotFormat(out, firstNode);
	}

	public String toThreeAddresscode(ThreeAddressCode tac, BasicBlock prev, boolean isFirst)
	{
		String temp1 = null,temp2 = null;
		for(int i = 0; i < children.size(); i ++)
		{
			if(i == 0)
				temp1 = children.get(i).factor.toThreeAddressCode(tac, prev);
			else {
				temp2 = tac.getTempVar();
				String tmp1 = children.get(i).factor.toThreeAddressCode(tac, prev);
				if(children.get(i).sign == '*')
					prev.addBinaryInstruction(compiler.tac.Instruction.Operator.Mul, temp2, temp1, tmp1);
				else {
					prev.addBinaryInstruction(compiler.tac.Instruction.Operator.Div, temp2, temp1, tmp1);
				}
				temp1 = temp2;
			}
			
		}
		if(isFirst && this.sign =='-')
		{	
			String tmp = tac.getTempVar();
			prev.addUnaryInstruction(compiler.tac.Instruction.Operator.Neg, tmp, temp1);
			temp1 = tmp;
		}
		return temp1;
	}
}
